package com.umakr.ax.xf;

import com.iflytek.cloud.speech.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;


/**
 * @author umakr
 */
public class RadioToWord {
    protected final Log logger = LogFactory.getLog(this.getClass());
    private static final String APPID = "5a73e14f";
    private StringBuilder mResult = new StringBuilder();


    /* 最大等待时间， 单位ms*/

    private static final int MAX_WAIT_TIME = 100000;
    private int maxWaitTime = MAX_WAIT_TIME;

    /* 每次等待时间 */


    private int perWaitTime = 100;

    /* 出现异常时最多重复次数 */


    private int maxQueueTimes = 3;

        /* 音频文件
         */

    private String fileName = "";

    static {
        Setting.setShowLog( true );
        SpeechUtility.createUtility(SpeechConstant.APPID +"="+ APPID);
    }

    public String voice2words(String fileName) throws InterruptedException, IOException {
        return voice2words(fileName, true);
    }


     /*
     *
     * @desc: 工具类，在应用中有一个实例即可， 但是该实例是有状态的， 因此要消除其他调用对状态的修改，所以提供一个init变量
     * @auth: zona
     * 2017年1月4日 下午4:38:45
     * @param fileName
     * @param init 是否初始化最大等待时间。
     * @return
     * @throws InterruptedException
     */


    public String voice2words(String fileName, boolean init) throws InterruptedException, IOException {
        if(init) {
            maxWaitTime = MAX_WAIT_TIME;
            maxQueueTimes = 3;
        }
        if(maxQueueTimes <= 0) {
            mResult.setLength(0);
            mResult.append("解析异常！");
            return mResult.toString();
        }
        this.fileName = fileName;

        return recognize();
    }


    // *************************************音频流听写*************************************


    /* *
     * 听写
     * @return
     * @throws InterruptedException
     */


    private String recognize() throws InterruptedException, IOException {
        if (SpeechRecognizer.getRecognizer() == null) {
            SpeechRecognizer.createRecognizer();
        }
        return recognizepcmfilebytefor();
    }


     /*
     * 自动化测试注意要点 如果直接从音频文件识别，需要模拟真实的音速，防止音频队列的堵塞
     * @throws InterruptedException
     */

    private String recognizepcmfilebytefor() throws InterruptedException, IOException {
        // 1、读取音频文件
        SpeechRecognizer recognizer = SpeechRecognizer.getRecognizer();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new File(fileName));
            mResult.setLength(0);
            recognizer.setParameter(SpeechConstant.DOMAIN, "iat");
            recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
            recognizer.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
            recognizer.setParameter(SpeechConstant.VAD_EOS,"2000");
            recognizer.setParameter( SpeechConstant.RESULT_TYPE, "plain" );
            recognizer.startListening(recListener);
            byte[] buffer = new byte[4800];
            int length = 0;
            while((length = fis.read(buffer)) != -1){
                recognizer.writeAudio(buffer, 0, length);
            }
        } catch (Exception e) {

            return "";
        } finally {
            try {
                if (null != fis) {
                    fis.close();
                }
            } catch (IOException e) {
                logger.info(e);
            }
        }
        // 2、音频流听写
            //解析之前将存出结果置为空
            recognizer.stopListening();
            // 在原有的代码基础上主要添加了这个while代码等待音频解析完成，recognizer.isListening()返回true，说明解析工作还在进行
            while(recognizer.isListening()) {
                if(maxWaitTime < 0) {
                    mResult.setLength(0);
                    mResult.append("解析超时！");
                    break;
                }
                Thread.sleep(perWaitTime);
                maxWaitTime -= perWaitTime;
            }
        return mResult.toString();
    }


     /*
     * 听写监听器
     * */



    private RecognizerListener recListener = new RecognizerListener() {

        @Override
        public void onBeginOfSpeech() {
            // Do nothing because of X and Y.
        }

        @Override
        public void onEndOfSpeech() {
            // Do nothing because of X and Y.
        }

        @Override
        public void onVolumeChanged(int volume) {
            // Do nothing because of X and Y.
        }

        @Override
        public void onResult(RecognizerResult result, boolean islast) {
            mResult.append(result.getResultString());
        }

        @Override
        public void onError(SpeechError error) {
            try {
                maxWaitTime = MAX_WAIT_TIME;
                voice2words(fileName);
                maxQueueTimes--;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } catch (IOException err) {
                logger.info(err);
                Thread.currentThread().interrupt();
            }
        }

        @Override
        public void onEvent(int eventType, int arg1, int agr2, String msg) {
            // Do nothing because of X and Y.
        }

    };

}
